﻿/*
  Copyright (c) 2011, Mikheev Rostislav
  Copyright (c) 2011, FreshFarsh team

  Steel Engine source code is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
/**
  @author Mikheev Rostislav <hacenator@gmail.com>
  @date 27.12.2010
  @brief Basic graphical structures defination
*/

#ifndef STEEL_STRUCTURES_H_
#define STEEL_STRUCTURES_H_

#include <stdint.h>
#include "GL/glew.h"
#include <common.h>

namespace _STEEL_NAMESPACE {

// forwad struct declarations
struct Point2i;
struct Point2f;
struct Curve2;
struct RGBColor;
struct RGBAColor;
struct Vertex2D;
struct Quad2D;
struct Matrix4x4f;
struct Matrix4x4d;


/**
* Rectangle
*/
struct Rect {
  int left, top, right, bottom;

  /// Default constructor
  Rect() : left(0), top(0), right(0), bottom(0) { }

  /// Initial constructor
  Rect(int top, int right, int bottom, int left);
};

//=============================================
//          Points
//=============================================
/**
        2D point of integer
*/
struct Point2i {
  union {
    int v[2];
    struct {
      int x, y;
    };
  };

  /// Default constructor
  Point2i() : x(0), y(0) { };

  /// Construct from too coordinates
  Point2i(float x, float y);

  /// Convert from Point2f
        Point2i& operator=(const Point2f& point);
};

/**
        2D Point of float
*/
struct Point2f {
  union {
    float v[2];
    struct {
      float x, y;
    };
  };

  /// Default constructor
  Point2f() : x(0), y(0) { };

  /// Construct from too coordinates
  Point2f(float x, float y);

  /// Convert from Point2i
  Point2f& operator=(const Point2i& point);
};

//=============================================
//          Curve
//=============================================
/**
    2D Curve of integer
*/
struct Curve2 {
  Point2f point;

  // intermediate points
  Point2f left_ipoint; ///< left intermediate points coord
  Point2f right_ipoint; ///< right intermediate points coord
};


//=============================================
//          Colors
//=============================================
/**
        RGBA (Red, Green, Blue, Alpha) color
*/
struct RGBAColor {
  union {
    uint8_t v[4];
    struct {
      uint8_t r, g, b, a;
    };
  };

  /// Default constructor
  RGBAColor() : r(0), g(0), b(0), a(255) {};

  /// Initial constructor
  RGBAColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a);

  /// From RGB
  RGBAColor& operator=(RGBColor& color);
};

/**
*  RGB (Red, Green, Blue) color
*/
struct RGBColor {
  union {
    uint8_t v[3];
    struct {
      uint8_t r, g, b;
    };
  };

  /// Default constructor
  RGBColor(void) : r(0), g(0), b(0) {};

  /// Initial constructor
  RGBColor(uint8_t r, uint8_t g, uint8_t b);

  /// From RGBA
  RGBColor& operator=(RGBAColor& color);
};

//=============================================
//          Textured points
//=============================================

// Textured Points offset macros
#define STRUCT_OFFSET(p, i) ((char *)p + (i))

/**
  2D vertex, point coordinate offset
*/
#define STRUCT_OFFSET_2D_POINT STRUCT_OFFSET(NULL, 0)

/**
  2D vertex, texture coordinate offset
*/
#define STRUCT_OFFSET_2D_TEXTURE STRUCT_OFFSET(NULL, 8)

/**
  2D vertex, color
*/
#define STRUCT_OFFSET_2D_COLOR STRUCT_OFFSET(NULL, 16)

/**
  Point with texture coordinates in 2D
*/
struct Vertex2D {
  Point2f point; ///< point coordinates
  Point2f texture; ///< texture coordinates
  RGBAColor color; ///< RGBA color
};

/**
 * Textured 2D Quad
 */
struct Quad2D {
  Vertex2D vertex[4];

  /// Default constructor
  Quad2D() { };

  // Constructor from Rect
  //Quad2D(const Rect &rect);

  /// Convert from Rect
  Quad2D& operator=(const Rect &rect);
};

//=============================================
//          Matrix4x4
//=============================================
/**
  4x4 Matrix of float
*/
struct Matrix4x4f {
  union {
    float element[4][4];
    float array[16];
  };
};

struct Matrix4x4d {
  union {
    double element[4][4];
    double array[16];
  };
};


/**
        Text Alignment
*/
enum TextAlign {
  AL_LEFT,
  AL_CENTER,
  AL_RIGHT
};

}

#endif // STEEL_STRUCTURES_H_
